﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Data;
using org.se.fs.presenter.IView.Template;
using org.se.fs.presenter.Library;

namespace org.se.fs.presenter.View.Loan
{
    public class BenefitLoanLists : Template.ViewLists
    {
        private readonly IFormLists _view;
        private readonly ITask.Loan.IRegularLoan _task;

        public BenefitLoanLists(IFormLists view) : this(view, new Task.Context.RegularLoan()) { }

        public BenefitLoanLists(IFormLists view, ITask.Loan.IRegularLoan task)
        {
            _view = view;
            _task = task;
        }

        public override void Initialize()
        {
            Lists = new DataTable();
            _task.OnGetCount += TaskOnGetCount;
            _task.OnFetchLists += TaskOnFetchLists;
            _task.OnDelete += TaskOnDelete;
            InitializeSearchOption();
            Search();
        }

        protected override void TaskOnFetchLists(object source, FormEvent e)
        {
            _view.EnableButtonSearch(true);
            _view.EnableResults(true);

            if (!e.IsSuccess)
            {
                _view.Lists = new DataTable();
                _view.StatusLists = "Result: 0 records";
                return;
            }

            Lists = (DataTable)e.Value;
            DisplayData();
        }

        protected override void TaskOnDelete(object source, FormEvent e)
        {
            TriggerDelete(new FormEvent(true) { Exception = e.Exception });

            if (!e.IsSuccess)
                return;

            var data = (DataTable)e.Value;
            foreach (var dr in Lists.Select().Where(dr => dr["id"].ToString().Equals(data.Rows[0]["id"].ToString())))
            {
                Lists.Rows.Remove(dr);
                break;
            }
            DisplayData();
        }

        protected override void TaskOnGetCount(object source, FormEvent e)
        {
            MaxRecords = (UInt16) e.Value;
            FetchRecords();
        }

        protected override void InitializeSearchOption()
        {
            SearchOption = new List<SearchOption>
                                {
                                    new SearchOption("Code", "code", typeof (string)),
                                    new SearchOption("Description", "description", typeof (string)),
                                    new SearchOption("Regular Amount", "regular_amount", typeof (decimal)),
                                    new SearchOption("Regular Interest", "regular_interest", typeof (decimal)),
                                    new SearchOption("Extended Interest", "extended_interest", typeof (decimal)),
                                    new SearchOption("Principal Amount", "principal_amount", typeof (decimal)),
                                    new SearchOption("Service Fee", "service_fee", typeof (decimal)),
                                    new SearchOption("Reloan", "is_re_loan", typeof (bool)),
                                    new SearchOption("Posted", "is_posted", typeof (bool))
                                };
            var type = (SearchOption.Select(a => a.Option)).ToArray();
            _view.FillType(type);
            _view.IndexType = -1;
        }

        public override void Remove(DataTable data)
        {
            if (data == null || Lists.Rows.Count.Equals(0) || data.Rows.Count.Equals(0))
                return;

            _task.Delete(data);
        }

        public override void Search()
        {
            _view.EnableButtonSearch(false);
            _task.GetCount();
        }

        protected override string GetFilterString()
        {
            if(string.IsNullOrEmpty(_view.SearchItem) || _view.IndexType.Equals(-1))
                return string.Empty;
            
            if (SearchOption[_view.IndexType].DataType.Equals(typeof(string)))
                return string.Format("{0} LIKE {1}%", SearchOption[_view.IndexType].Filter, _view.SearchItem);
            return string.Format("{0} {1}", SearchOption[_view.IndexType].Filter, _view.SearchItem);
        }

        protected override void FetchRecords()
        {
            _view.EnableResults(false);
            _task.FetchLists(new PagingLists(CurrPage, GetFilterString()));
        }

        public override void DisplayData()
        {
            _view.StatusLists = string.Format("Result: {0} records", Lists.Rows.Count);

            if (Lists.Rows.Count.Equals(0))
                _view.Lists = new DataTable();

            SetStatusPage();
        
            var a = (Lists.AsEnumerable().OrderBy(b => b.Field<DateTime>("created_date")));
            Lists = a.CopyToDataTable();

            var d = (Lists.AsEnumerable().Select(c => new
                                                          {
                                                              Code = c.Field<string>("code"),
                                                              Description = c.Field<string>("description"),
                                                              RegAmount = Common.FormatNumeric(c.Field<decimal>("regular_amount")),
                                                              RegInterest = Common.FormatNumeric(c.Field<decimal>("regular_interest")) + "%",
                                                              ExtInterest = Common.FormatNumeric(c.Field<decimal>("extended_interest")) + "%",
                                                              PrincipalAmount = Common.FormatNumeric(c.Field<decimal>("principal_amount")),
                                                              Fee = Common.FormatNumeric(c.Field<decimal>("service_fee")),
                                                              Reloan = c.Field<bool>("is_re_loan") ? "YES" : "NO",
                                                              Posted = c.Field<bool>("is_posted") ? "YES" : "NO"
                                                          })).ToArray();
            _view.Lists = d;
        }

        protected override void SetStatusPage()
        {
            if (CurrPage <= Config.MaxPageSize)
            {
                _view.EnableButtonRecordFirst(false);
                _view.EnableButtonRecordPrevious(false);
            }

            if (CurrPage + Config.MaxPageSize >= MaxRecords)
            {
                _view.EnableButtonRecordNext(false);
                _view.EnableButtonRecordLast(false);
            }

            _view.StatusPage = string.Format("( {0} / {1} of {2} Records)", CurrPage, CurrPage + Config.MaxPageSize,
                                             MaxRecords);
        }
    }
}
